package com.changsideal.tool;

import com.changsideal.excel.annotation.Column;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @ClassName BasicTool
 * @Description TODO
 * @Author Create by Chansideal.Haosc
 * @Date 2019/7/9 9:36
 * @Version 1.0
 **/
public class BasicTool {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(Constant.CSTFORMAT);

    public static String buildCTPCodeKey(Integer entryKey) {
        return buildCTPCodeKey(9, entryKey);
    }

    private static String buildCTPCodeKey(int length, Integer entryKey) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(Constant.RANDOM_CHARACTER.length());
            sb.append(Constant.RANDOM_CHARACTER.charAt(number));
        }
        return Constant.INVOCATION_KEY + entryKey + "-"
                + random.nextInt(Constant.INVOCATION_HASHCODE) + sb.toString();
    }

    public static String entrySecret(Integer orderNum) {
        return Constant.INVOCATION_KEY + "-" + orderNum + "-" + Constant.INVOCATION_HASHCODE;
    }

    public static boolean checkOrNull(Object object) {
        return object == null;
    }

    public static Object changeType(String typeName, String importStr) {
        // 此处避免了excel在导入后有些数字后面出现.0的情况，会导致转型抛异常
        importStr = importStr.replace(".0", "");
        if (Constant.STRING.equals(typeName)) {
            return importStr;
        }

        if (Constant.INTEGER.equals(typeName)) {
            return Integer.parseInt(importStr);
        }

        if (Constant.FLOAT.equals(typeName)) {
            return Float.parseFloat(importStr);
        }

        if (Constant.DOUBLE.equals(typeName)) {
            return Double.parseDouble(importStr);
        }

        if (Constant.BOOLEAN.equals(typeName)) {
            return Boolean.parseBoolean(importStr);
        }

        if (Constant.SHORT.equals(typeName)) {
            return Short.parseShort(importStr);
        }

        if (Constant.DATE.equals(typeName)) {
            LocalDateTime parse = LocalDateTime.parse(importStr, FORMATTER.withLocale(Locale.US));
            return Date.from(parse.atZone(ZoneId.systemDefault()).toInstant());
        }
        return null;
    }

    public static String invocationString(Object object) {
        if (checkOrNull(object)) {
            return null;
        }
        String typeStr = object.getClass().getTypeName();
        if (Constant.STRING.equals(typeStr)) {
            return object.toString();
        }
        if (Constant.INTEGER.equals(typeStr)
                || Constant.FLOAT.equals(typeStr)
                || Constant.DOUBLE.equals(typeStr)
                || Constant.BOOLEAN.equals(typeStr)
                || Constant.SHORT.equals(typeStr)) {
            return String.valueOf(object);
        }

        if (Constant.DATE.equals(typeStr)) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constant.YEARFORMAT);
            simpleDateFormat.setLenient(false);
            return simpleDateFormat.format(object);
        }
        return null;
    }

    private static List<Field> mainOrder(Class classT) {
        // 获取当前传入class的所有包含私有的属性
        Field[] declaredFields = classT.getDeclaredFields();
        List<Field> list = new LinkedList<>();
        List<Field> orderList = new LinkedList<>();
        // 获取每条属性的注解信息解析
        for (Field declaredField : declaredFields) {
            Column annotation;
            // 条件：属性成员为私有，必须有Column注解，Column注解必须是导入标识为真则进行处理
            if (Modifier.isPrivate(declaredField.getModifiers())
                    && (annotation = declaredField.getAnnotation(Column.class)) != null
                    && declaredField.getAnnotation(Column.class).importFlag()) {
                // 解析sql，判断sqlflag是否为真，为真则说明此属性参与sql生成
                if (annotation.sqlFlag()) {
                    // 判断sql语句成员顺序的值是否是负数，如为负数则直接不参与sql生成，继续执行下一个属性判断
                    if (annotation.sqlOrder() < 0) {
                        continue;
                    }
                    // 如果排序值为默认0，则按遍历顺序进行排序操作
                    if (annotation.sqlOrder() == 0) {
                        ((LinkedList<Field>) list).addLast(declaredField);
                        // 如果序号大于0，则放置到待后续排序队列中
                    } else {
                        orderList.add(declaredField);
                    }
                }
            }
        }

        if (orderList.size() > 0) {
            orderList.sort(new ExcelOrderCompare());
            list.addAll(orderList);
        }
        return list;
    }

    /** 获取注解排序后的拼装sql字段顺序，返回为组装完成的列值字符串 **/
    public static String magicColumnOrder(Class conditionClass) {
        List<Field> analysisList = mainOrder(conditionClass);
        List<String> nameList = new ArrayList<>(analysisList.size());
        for (Field field : analysisList) {
            nameList.add(field.getName());
        }
        String result = nameList.toString();
        return result.substring(1, result.length() - 1);
    }

    /** 获取注解排序后的属性顺序，用于之后自助取值处理 **/
    public static List<Field> magicFiledOrder(Class conditionClass){
        return mainOrder(conditionClass);
    }
}
